package com.yxy.springcloud.framework.unionauth.service;

import com.alibaba.fastjson.JSON;
import com.yxy.springcloud.framework.common.base.BusinessException;
import com.yxy.springcloud.framework.common.utils.CommonUtils;
import com.yxy.springcloud.framework.common.utils.MD5Util;
import com.yxy.springcloud.framework.unionauth.DTO.ChangePasswordDto;
import com.yxy.springcloud.framework.unionauth.dao.AuthAdminUserMapper;
import com.yxy.springcloud.framework.unionauth.model.AuthAdminUser;
import com.yxy.springcloud.framework.unionauth.utils.TokenCheckUtil;
import com.yxy.springcloud.framework.unionauth.vo.LoginUserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class LoginService {

  @Resource
  private AuthAdminUserMapper loginUserMapper;

  @Autowired
  private TokenCheckUtil tokenCheckUtil;

  @Autowired
  private HttpServletRequest httpServletRequest;

  public Map<String, Object> in(AuthAdminUser inputDto) throws BusinessException {
    AuthAdminUser queryObj = new AuthAdminUser();
    queryObj.setUsername(inputDto.getUsername());
    queryObj.setPassword(MD5Util.stringMD5(inputDto.getPassword()).toLowerCase());
    AuthAdminUser adminUser = loginUserMapper.selectOne(queryObj);
    if (adminUser == null) {
      log.error("用户名或密码错误 {}", inputDto);
      throw new BusinessException(500, "用户名或密码错误");
    }

    String token = "auth#token#" + CommonUtils.generateUUID();
    //保存token到set中
    tokenCheckUtil.pushToken(token, adminUser);
    Map<String, Object> map = new HashMap<>();
    map.put("token", token);
    return map;
  }

  public void out() {
    String token = httpServletRequest.getHeader("x-token");
    tokenCheckUtil.deleteToken(token);
  }

  //管理用户修改个人信息
  @Transactional(rollbackFor = Exception.class)
  public void update(AuthAdminUser inputDto) throws BusinessException {
    String curUserStr = tokenCheckUtil.getUserInfoByToken();
    AuthAdminUser curUser = JSON.parseObject(curUserStr, AuthAdminUser.class);
    if (!curUser.getId().equals(inputDto.getId())) {
      log.error("用户id不匹配,无法修改信息,请重新登录");
      throw new BusinessException(502, "用户id不匹配,无法修改信息,请重新登录");
    }
    // 修改用户特定信息
    AuthAdminUser updateObj = new AuthAdminUser();
    updateObj.setId(inputDto.getId());
    updateObj.setName(inputDto.getName());
    updateObj.setUsername(inputDto.getUsername());
    updateObj.setPassword(MD5Util.stringMD5(inputDto.getPassword()).toLowerCase());

    updateObj.setUpdateUserId(curUser.getId());
    updateObj.setUpdateUserName(curUser.getUsername());
    updateObj.setUpdateDate(new Date());
    loginUserMapper.updateByPrimaryKeySelective(updateObj);
  }

  // 管理用户登录后紧接着获取用户详情
  public LoginUserVO userInfo(String token) throws BusinessException {
    String curUserStr = tokenCheckUtil.getUserInfoByToken();
    AuthAdminUser curUser = JSON.parseObject(curUserStr, AuthAdminUser.class);

    LoginUserVO vo = new LoginUserVO();
    BeanUtils.copyProperties(curUser, vo);

    // 设置role
    vo.getRoles().add("authSuperAdmin");
    return vo;
  }

  public void changePassword(ChangePasswordDto inputDto) throws BusinessException {
    String oldPassword = inputDto.getOldPassword();
    String newPassword = inputDto.getNewPassword();

    String curUserStr = tokenCheckUtil.getUserInfoByToken();
    AuthAdminUser curUser = JSON.parseObject(curUserStr, AuthAdminUser.class);
    long userId = curUser.getId();
    String oldPasswordMd5 = curUser.getPassword();
    // 检验旧密码是否正确
    String oldPasswordMd5FromInput = MD5Util.stringMD5(oldPassword).toLowerCase();
    if (!oldPasswordMd5.equals(oldPasswordMd5FromInput)) {
      throw new BusinessException(521, "旧密码不正确");
    }
    // 设置为新密码
    AuthAdminUser updateObj = new AuthAdminUser();
    updateObj.setId(userId);
    updateObj.setPassword(MD5Util.stringMD5(newPassword).toLowerCase());
    updateObj.setUpdateDate(new Date());
    updateObj.setUpdateUserId(userId);
    updateObj.setUpdateUserName(curUser.getName());
    loginUserMapper.updateByPrimaryKeySelective(updateObj);
  }
}
